package cc.linker.steplink.crm.merchanth5.service.redis;

import cc.linker.steplink.crm.commons.BeanMapUtils;
import cc.linker.steplink.crm.commons.CrmRedisKeys;
import cc.linker.steplink.crm.merchanth5.dao.*;
import cc.linker.steplink.crm.merchanth5.dao.acs.PurchaseProcessDao;
import cc.linker.steplink.crm.merchanth5.dao.integral.IntegralH5Dao;
import cc.linker.steplink.crm.merchanth5.pojo.MallGoodsSkuPo;
import cc.linker.steplink.crm.merchanth5.pojo.MallGoodsSpecPo;
import cc.linker.steplink.crm.merchanth5.pojo.ShoppingCartGoodsPo;
import cc.linker.steplink.crm.merchanth5.pojo.acs.GoodsParamPo;
import cc.linker.steplink.crm.merchanth5.pojo.integral.IntegralGoodsPo;
import cc.linker.steplink.crm.response.GlobalException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: CKQ
 * @DateTime: 2020/6/11 17:52
 * @Description: TODO
 */
@EnableAsync
@Service
public class GoodsService {
    @Autowired
    private MaiBaoLaDao maiBaoLaDao;

    @Autowired
    private MallDao mallDao;

    @Autowired
    private ZsContentDao zsContentDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ColumnDao columnDao;

    @Autowired
    private PurchaseProcessDao purchaseProcessDao;

    @Autowired
    private IntegralH5Dao integralH5Dao;

//    public String GOODS_INFO_KEY = "goodsInfo:goods_info_";
//    public String CONTENT_INFO_KEY = "goodsInfo:content_info_";
//    public String COLUMN_INFO_KEY = "goodsInfo:column_info_";
//    public String GOODS_SKU_INFO_KEY = "goodsInfo:sku_info_";
//    public String GOODS_SPEC_INFO_KEY = "goodsInfo:spec_info_";
//    public String cartGoodsSkuInfoKey = "cartGoodsInfo:goods_sku_info_";
//    // todo
//    //{goods}保持唯一暂时不占用 {goods}goods:goods_count_+#{goodsId}
//    public String goodsCountKey = "{goods}goods:goods_count_";
//    //{goods}保持唯一暂时不占用 {goods}goods:goods_count_+#{goodsId}+_#{skuId}
//    public String skuCountKey = "{goods}goods:sku_count_";
//    public String COLUMN_CONTENTS_KEY = "home:column_list_";
//    public String goodsVip = "{vip}:vip_";


    /*
     * 获取商品信息，不写入缓存
     * */
    public Map getGoodsInfoNotWriteRedis(String goodsId) {
        Map<String, Object> goodsInfo = new HashMap<>();
        String goodsInfoStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsInfoStr)) {
            goodsInfo = maiBaoLaDao.getGoodsByGoodsId(goodsId);
        } else {
            goodsInfo = (Map<String, Object>) JSON.parse(goodsInfoStr);
        }
        return goodsInfo;
    }

    public IntegralGoodsPo getIntegralGoodsInfo (Long goodsId){
        return integralH5Dao.getIntegralGoodsInfo(goodsId);
    }

    public List<IntegralGoodsPo> getIntegralGoodsByIds(String goodsIds) {
        return integralH5Dao.getIntegralGoodsByIds(goodsIds);
    }


    /*
     * 通过商品ID获取商品信息
     * */
    public Map getGoodsInfo(String goodsId) throws GlobalException {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, Object> goodsInfo = new HashMap<>();
        String goodsInfoStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsInfoStr)) {
            goodsInfo = maiBaoLaDao.getGoodsByGoodsId(goodsId);
            if (goodsInfo != null && goodsInfo.containsKey("upTime") && !StringUtils.isEmpty(goodsInfo.get("upTime"))) {
                Date d = (Date) goodsInfo.get("upTime");
                goodsInfo.put("upTime", fmt.format(d));
            }
            if (goodsInfo != null && goodsInfo.containsKey("overTime") && !StringUtils.isEmpty(goodsInfo.get("overTime"))) {
                Date overTime = (Date) goodsInfo.get("overTime");
                goodsInfo.put("overTime", fmt.format(overTime));
            }

            if (goodsInfo != null && goodsInfo.containsKey("quotaVip") && !StringUtils.isEmpty(goodsInfo.get("quotaVip"))) {
                String quotaVipString = goodsInfo.get("quotaVip").toString();
                List<QuotaPo> quotaVips= JSONArray.parseArray(quotaVipString, QuotaPo.class);
                if(quotaVips!=null && quotaVips.size()>0){
                    Integer isNull = 1;
                    for(QuotaPo quotaPo : quotaVips){
                        Long vipId = quotaPo.getVipId();
                        if(vipId!=null){
                            String vipName = maiBaoLaDao.getVipNameByVipId(vipId);
                            quotaPo.setVipName(vipName);
                            //vip和商品的限购关系
                            stringRedisTemplate.opsForSet().add(CrmRedisKeys.goodsVip+vipId,goodsId);
                            isNull = 0;
                        }
                    }
                    if(isNull==0){
                        goodsInfo.put("quotaVip",JSON.toJSON(quotaVips));
                    }else {
                        goodsInfo.remove("quotaVip");
                    }

                }
            }
            if (goodsInfo != null && goodsInfo.containsKey("quotaLevel") && !StringUtils.isEmpty(goodsInfo.get("quotaLevel"))) {
                String quotaLevelString = goodsInfo.get("quotaLevel").toString();
                QuotaPo quotaLevel= JSON.parseObject(quotaLevelString,QuotaPo.class);
                if(quotaLevel.getLevel()!=null){
                    String levelName = "vip0";
                    if(quotaLevel.getLevel()!=null){
                        levelName = maiBaoLaDao.getVipNameByLevelOrder(quotaLevel.getLevel(),goodsInfo.get("orgId").toString());
                    }
                    quotaLevel.setLevelName(levelName);
                    goodsInfo.put("quotaLevel",JSON.toJSON(quotaLevel));
                }else {
                    goodsInfo.remove("quotaLevel");
                }

            }
            stringRedisTemplate.opsForValue().set(CrmRedisKeys.GOODS_INFO_KEY + goodsId, JSON.toJSONString(goodsInfo, SerializerFeature.WriteMapNullValue));
        } else {
            goodsInfo = (Map<String, Object>) JSON.parse(goodsInfoStr);
        }
        if (!StringUtils.isEmpty(goodsInfo.get("mallsGoodsId"))) {
            goodsId = goodsInfo.get("mallsGoodsId").toString();
        }
        Date overTime = null;
        Date nowTime = new Date();
        if (goodsInfo != null && goodsInfo.containsKey("overTime") && !StringUtils.isEmpty(goodsInfo.get("overTime"))) {
            try{
                overTime =fmt.parse(goodsInfo.get("overTime").toString());
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(overTime!=null && overTime.before(nowTime)){
            //如果定时售罄时间过了，库存显示为0
            goodsInfo.put("goodsCount","0");
        }else {
            String goodsCount = stringRedisTemplate.opsForValue().get(CrmRedisKeys.goodsCountKey + goodsId);
            if(StringUtils.isEmpty(goodsCount)){
                goodsCount = "0";
            }
            goodsInfo.put("goodsCount", Integer.parseInt(goodsCount));
        }

        return goodsInfo;
    }

    public List<Map> getGoodsByIds(String goodsIds) {
        List<Map>  goodsList = maiBaoLaDao.goodsList(goodsIds);
        return goodsList;
    }


    /**
     * 通过商品ID获取
     */
    public GoodsParamPo getGoodsParamPoByGoodsId(Long goodsId) {
        GoodsParamPo goodsParamPo = new GoodsParamPo();
        String goodsInfoStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsInfoStr)) {
            goodsParamPo = purchaseProcessDao.getAllByGoodsId(goodsId);
        } else {
            Map<String, Object> goodsMap = new HashMap<>();
            goodsMap = (Map<String, Object>) JSON.parse(goodsInfoStr);
            goodsParamPo.setType(goodsMap.containsKey("promotion") ? Integer.valueOf(goodsMap.get("promotion").toString()) : 0);
            goodsParamPo.setBelongId(goodsMap.containsKey("belongId") ? goodsMap.get("belongId").toString() : "");
            goodsParamPo.setMallsGoodsId((goodsMap.containsKey("mallsGoodsId") && goodsMap.get("mallsGoodsId")!=null) ? Long.valueOf(goodsMap.get("mallsGoodsId").toString()) : null);
            goodsParamPo.setRebateStr(goodsMap.containsKey("promotionRebate") ? goodsMap.get("promotionRebate").toString() : "");
            goodsParamPo.setOrgId(goodsMap.containsKey("orgId") ? goodsMap.get("orgId").toString() : "");
        }
        return goodsParamPo;
    }

    /**
     * 获取sku信息
     */
    public Map getGoodsSku(String goodsId) {
        Map<String, Map> map = new LinkedHashMap<>();
        String goodsSkuPosStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_SKU_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsSkuPosStr)) {
            List<MallGoodsSkuPo> goodsSkuPos = mallDao.getMerchantGoodsSku(goodsId);
            for (MallGoodsSkuPo po : goodsSkuPos) {
                map.put(po.getSkuKey(), BeanMapUtils.beanToMap(po));
            }
            stringRedisTemplate.opsForValue().set(CrmRedisKeys.GOODS_SKU_INFO_KEY + goodsId, JSON.toJSONString(map, SerializerFeature.WriteMapNullValue));
        } else {
            map = JSON.parseObject(goodsSkuPosStr, Map.class);
        }
        Map goodsInfo = getGoodsInfo(goodsId);
        for (Map.Entry<String, Map> entry : map.entrySet()) {
            Map value = entry.getValue();
            String tmpGoodsId = goodsId;
            String skuId = value.get("skuId").toString();
            if (!StringUtils.isEmpty(value.get("mallsSkuId"))) {
                skuId  = value.get("mallsSkuId").toString();
                tmpGoodsId = goodsInfo.get("mallsGoodsId").toString();
            }
            if(goodsInfo!=null && !StringUtils.isEmpty(goodsInfo.get("goodsCount")) && "0".equals(goodsInfo.get("goodsCount").toString())){
                value.put("goodsCount", 0);
            }else {
                String rkey = CrmRedisKeys.skuCountKey + tmpGoodsId + "_" + skuId;
                String goodsCount = stringRedisTemplate.opsForValue().get(rkey);
                if (StringUtils.isEmpty(goodsCount)) {
                    goodsCount = "0";
                }
                value.put("goodsCount", Integer.parseInt(goodsCount));
            }
        }
        return map;
    }

    /**
     * 获取spec信息
     */
    public List<MallGoodsSpecPo> getGoodsSpec(String goodsId) {
        Map<String, MallGoodsSpecPo> sepcList;
        String goodsSpecPosStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_SPEC_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsSpecPosStr)) {
            List<MallGoodsSpecPo> specPos = mallDao.getMerchantGoodsSpec(goodsId);
            stringRedisTemplate.opsForValue().set(CrmRedisKeys.GOODS_SPEC_INFO_KEY + goodsId, JSON.toJSONString(specPos, SerializerFeature.WriteMapNullValue));
            return specPos;
        } else {
            return JSON.parseArray(goodsSpecPosStr, MallGoodsSpecPo.class);
        }
    }

    /*
     * 获取内容的缓存数据
     * */
    public Map<String, Object> getContentGoodsInfo(String goodsId) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String goodsContentPosStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(goodsContentPosStr)) {
            Map<String, Object> content = zsContentDao.getContentInof(goodsId);
            if (content != null && content.containsKey("updateTime") && !StringUtils.isEmpty(content.get("updateTime"))) {
                Date d = (Date) content.get("updateTime");
                content.put("updateTime", fmt.format(d));
            }
            stringRedisTemplate.opsForValue().set(CrmRedisKeys.GOODS_INFO_KEY + goodsId, JSON.toJSONString(content, SerializerFeature.WriteMapNullValue));
            return content;

        } else {
            return (Map) JSON.parse(goodsContentPosStr);
        }
    }

    /**
     * 获取栏目数据
     */
    public Map<String, Object> getCloumnGoodsInfo(String customerId, String goodsId) {
        String cloumnGoodsInfoStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
        if (StringUtils.isEmpty(cloumnGoodsInfoStr)) {
            Map<String, Object> cloumnGoodsInfo = columnDao.getDetail(goodsId, customerId);
            if(cloumnGoodsInfo!=null) {
                stringRedisTemplate.opsForValue().set(CrmRedisKeys.GOODS_INFO_KEY + goodsId, JSON.toJSONString(cloumnGoodsInfo, SerializerFeature.WriteMapNullValue));
                return cloumnGoodsInfo;
            }else{
                return null;
            }
        } else {
            return (Map) JSON.parse(cloumnGoodsInfoStr);
        }
    }

    /*
     * 通过栏目ID获取栏目下的所有内容
     * */
    public List<Map<String, Object>> getColumnContents(String columnId, String orderBy) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        String columnGoodsInfoStr = stringRedisTemplate.opsForValue().get(CrmRedisKeys.COLUMN_CONTENTS_KEY + columnId + "_" + orderBy);
        if (StringUtils.isEmpty(columnGoodsInfoStr)) {
            List<Map<String, Object>> columnList = columnDao.getColumnContents(columnId, orderBy);
            columnList.forEach(item -> {
                Date d = (Date) item.get("createTime");
                item.put("createTime", fmt.format(d));
            });
            stringRedisTemplate.opsForValue().set(CrmRedisKeys.COLUMN_CONTENTS_KEY + columnId + "_" + orderBy, JSON.toJSONString(columnList, SerializerFeature.WriteMapNullValue), 1, TimeUnit.MINUTES);
            return columnList;
        } else {
            return (List) JSON.parseArray(columnGoodsInfoStr);
        }
    }


    /*
     * 获取购物车sku信息
     * */
    public ShoppingCartGoodsPo getGoodsSkuInfo(Map<String, Object> param) {
        String goodsId = "", skuId = "";
        if (param.containsKey("goodsId") && !StringUtils.isEmpty(param.get("goodsId"))) {
            goodsId = param.get("goodsId").toString();
        }
        if (param.containsKey("skuId") && !StringUtils.isEmpty(param.get("skuId"))) {
            skuId = param.get("skuId").toString();
        }
        String key = CrmRedisKeys.cartGoodsSkuInfoKey + goodsId + skuId;
        String cartGoodsSku = stringRedisTemplate.opsForValue().get(key);
        ShoppingCartGoodsPo goodsPo;
        if (StringUtils.isEmpty(cartGoodsSku)) {
            goodsPo = mallDao.getShoppingGoodsInfo(param);
            if (null != goodsPo) {
                stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(goodsPo, SerializerFeature.WriteMapNullValue));
                stringRedisTemplate.expire(key, 60, TimeUnit.SECONDS);
            }
        } else {
            goodsPo = JSON.parseObject(cartGoodsSku, ShoppingCartGoodsPo.class);
        }
        return goodsPo;
    }

    /*
     * 通过商品ID和skuid获取malsSkuid
     * */
    public Long getCreateOrderMallsSkuId(Long goodsId, Long skuId) {
        Long mallsSkuId = null;
        Map<String, Map> skuList = this.getGoodsSku(goodsId.toString());
        for (Map.Entry<String, Map> entry : skuList.entrySet()) {
            Map value = entry.getValue();
            if (value.get("skuId").toString().equals(skuId.toString())) {
                mallsSkuId = value.containsKey("mallsSkuId") && !StringUtils.isEmpty(value.get("mallsSkuId")) ? Long.valueOf(value.get("mallsSkuId").toString()) : null;
            }
        }
        return mallsSkuId;
    }

    /**
     * 通过供货商商品ID和skuid获取对应的供货价
     */
    public Integer getCreateOrderMallsAmount(Long goodsId, Long skuId) {
        //如果skuId 是null直接拿单规格的供货价
        Integer mallsAmount = 0;
        if (skuId == null) {
            Map goodsMap = this.getGoodsInfo(goodsId.toString());
            mallsAmount = goodsMap.containsKey("mallsAmount") && !StringUtils.isEmpty(goodsMap.get("mallsAmount")) ? Integer.valueOf(goodsMap.get("mallsAmount").toString()) : 0;
        } else {
            Map<String, Map> skuList = this.getGoodsSku(goodsId.toString());
            for (Map.Entry<String, Map> entry : skuList.entrySet()) {
                Map value = entry.getValue();
                if (value.get("skuId").toString().equals(skuId.toString())) {
                    mallsAmount = value.containsKey("mallsAmount") && !StringUtils.isEmpty(value.get("mallsAmount")) ? Integer.valueOf(value.get("mallsAmount").toString()) : 0;
                }
            }
        }
        return mallsAmount;
    }


    /**
     * vip修改清除商品缓存
     */
    @Async
    public void deleteGoodsRedisByVip(String vipId) {
        Set<String> set= stringRedisTemplate.opsForSet().members(CrmRedisKeys.goodsVip+vipId);
        if(set!=null && set.size()>0){
//            stringRedisTemplate.opsForValue().set(GOODS_INFO_KEY + goodsId, JSON.toJSONString(goodsInfo, SerializerFeature.WriteMapNullValue));
            for (String goodsId : set){
                stringRedisTemplate.delete(CrmRedisKeys.GOODS_INFO_KEY + goodsId);
            }
        }
    }



}
